Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix a memory leak with command modules #2017

Merged
merged 1 commit into from
Feb 1, 2021

Conversation

alexcrichton
Copy link
Member

@alexcrichton alexcrichton commented Jul 14, 2020

This commit fixes a memory leak that can happen with Linker::module
when the provided module is a command. This function creates a closure
but the closure closed over a strong reference to Store (and
transitively through any imports provided). Unfortunately a Store
keeps everything alive, including Func, so this meant that Store was
inserted into a cycle which caused the leak.

The cycle here is manually broken by closing over the raw value of each
external value rather than the external value itself (which has a
strong reference to Store).

@github-actions github-actions bot added the wasmtime:api Related to the API of the `wasmtime` crate itself label Jul 14, 2020
@github-actions
Copy link

Subscribe to Label Action

cc @peterhuene

This issue or pull request has been labeled: "wasmtime:api"

Thus the following users have been cc'd because of the following labels:

  • peterhuene: wasmtime:api

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

let imports = imports
.iter()
.map(|i| i.upgrade().unwrap())
.collect::<Vec<_>>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not immediately clear to me how this fixes the cycle. Func also contains a strong StoreInstanceHandle and Instance contains a strong Store, so is there already a cycle?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is that a strong reference to Store was closed over in the Func, which meant that Store basically had a strong reference to itself. By only closing over weak references that reference is broken at least. Each of the captures here only capture a weak version of the Store or external item.

This commit fixes a memory leak that can happen with `Linker::module`
when the provided module is a command. This function creates a closure
but the closure closed over a strong reference to `Store` (and
transitively through any imports provided). Unfortunately a `Store`
keeps everything alive, including `Func`, so this meant that `Store` was
inserted into a cycle which caused the leak.

The cycle here is manually broken by closing over the raw value of each
external value rather than the external value itself (which has a
strong reference to `Store`).
@alexcrichton
Copy link
Member Author

@sunfishcode mind taking another look at this?

@alexcrichton alexcrichton merged commit cb7b1aa into bytecodealliance:main Feb 1, 2021
@alexcrichton alexcrichton deleted the fix-leak branch February 1, 2021 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wasmtime:api Related to the API of the `wasmtime` crate itself
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants